#include "PropertyFactory.h"
#include <assert.h>
#include "PropertyMaker.h"
#include "IProperty.h"

namespace XF
{
	PropertyFactory::PropertyFactory()
	{
	}

	PropertyFactory::~PropertyFactory()
	{
	}

	void PropertyFactory::RegisterMaker( std::string id, std::string typeId, PropertyMakerBase* maker)
	{
		std::map<std::string, PropertyMakerBase*> *makersList = MakersList();
		std::map<std::string, std::string> *makersClassLinkList = MakersClassLinkList();

		assert(makersList->find(id) == makersList->end() && "PropertyFactory::RegisterMaker: Attempting to register maker with existing id: ");

		makersList->insert(std::make_pair(id, maker));
		makersClassLinkList->insert(std::make_pair(typeId, id));
	}

	void PropertyFactory::UnregisterMaker( std::string id )
	{
		std::map<std::string, PropertyMakerBase*> *makersList = MakersList();
		std::map<std::string, std::string> *makersClassLinkList = MakersClassLinkList();

		assert(makersList->find(id) != makersList->end() && "PropertyFactory::UnregisterMaker: Attempting to unregister maker with id that doesn;t exist: ");

		makersList->erase(id);

		// Might need to remove from MakersClassLinkList
	}

	IProperty* PropertyFactory::CreateProperty(const std::string &id, const std::string &name)
	{
		std::map<std::string, PropertyMakerBase*> *makersList = MakersList();

		std::map<std::string, PropertyMakerBase*>::iterator it = makersList->find(id);

		assert((it != makersList->end()) && "PropertyFactory::CreateProperty: Attempting to create property with unknown id: ");

		return it->second->MakeProperty(name);
	}

	IProperty* PropertyFactory::CreateProperty(const std::string &id, const std::string &name, const std::string &initialValue )
	{
		std::map<std::string, PropertyMakerBase*> *makersList = MakersList();

		std::map<std::string, PropertyMakerBase*>::iterator it = makersList->find(id);

		assert(it != makersList->end() && "PropertyFactory::CreateProperty: Attempting to create property with unknown id: ");

		IProperty* prop = (*it).second->MakeProperty(name);
		prop->SetFromString(initialValue);
		return prop;
	}

	std::map<std::string, PropertyMakerBase*>* PropertyFactory::MakersList()
	{
		static std::map<std::string, PropertyMakerBase*> *makersList 
			= new std::map<std::string, PropertyMakerBase*>();

		return makersList;
	}

	std::map<std::string, std::string>* PropertyFactory::MakersClassLinkList()
	{
		static std::map<std::string, std::string> *makersClassLinkList 
			= new std::map<std::string, std::string>();

		return makersClassLinkList;
	}
}
